
import { toRaw, unref, isRef } from "vue"
// import BaseArray from "../base2/base-array"

type myObject = {
  [key: string]: any
}

/**
 * 深层设置属性值，保留原属性，然后覆盖新属性值 options
 * @param target 目标
 * @param _source 来源
 */
export function deepSet(target: myObject, _source: myObject) {
  // 取原型
  const source = (_source.$toRaw) ? _source.$toRaw() : toRaw(_source)
  // 遍历原，判断属性类型
  Object.keys(source).forEach(key => {
    switch(typeof source[key]) {
      case 'object' :
        if (Array.isArray(source[key])) {
          // 数组
          if (Array.isArray(target[key])) {
            target[key].length = 0
          } else {
            target[key] = [] // new BaseArray([])
          }
          target[key].push(...source[key])
        } else {
          if (!target[key]) { // 没有定义
            target[key] = {}
          }
          if (source[key] === null) {
            target[key] = null
          } else {
            deepSet(target[key], source[key])
          }
        }
        break
      case 'bigint':
      case 'boolean':
      case 'number':
      case 'string':
        target[key] = source[key]
        break
      default:
        // 拷贝
        target[key] = source[key]
        break
    }
  })
  return target
}

/**
 * 深层拷贝，只拷贝数据，新对象
 * @param target 目标，空的
 * @param  _source 来源
 */
export function deepClone(target: myObject, _source: myObject) {
    // 取原型 toRaw
    const source = (_source.$toRaw) ? _source.$toRaw() : (_source)
    // 遍历原，判断属性类型
    Object.keys(source).forEach((key: string) => {
      switch(typeof source[key]) {
        case 'object' :
          if (Array.isArray(source[key])) {
            // 数组，使用扩展的子类
            target[key] = [] // new BaseArray(source[key])
            // target[key] = []
            // target[key].push(...source[key])
          } else {
            target[key] = {}
            deepClone(target[key], source[key])
          }
          break
        case 'bigint':
        case 'boolean':
        case 'number':
        case 'string':
          target[key] = source[key] ?? ''
          break      
        default:
          // 不拷贝
          target[key] = source[key]
          break
      }
    })
    return target
}


/**
 * 以 target 的属性为准，进行赋值。支持部分深层copy
 * * 如果属性是数组的话，可以保持响应性，但是不支持深层copy
 * * 如果属性是对象的话，可以支持深考
 * * 如果 有 $state，会调用。
 * @param target 目标
 * @param source 源
 */
export const copy = (target: myObject, source: myObject) => {
  const _this = target
  const _source = toRaw(source)

  // 以 原定状态的属性为准遍历，不增加、减少属性
  Object.keys(_this).forEach((key: string) => {
  // for (const key in _this) {
    const _val = unref(_source[key]) // 应对 ref 取值
    const _target = unref(_this[key])

    if (_val) { // 如果有值
      if (_target.$state) { // 对象、数组可以有 $state。
        _target.$state = _val
      } else {
        if (Array.isArray(_target)) { // 数组的话，需要保持响应性
          _target.length = 0
          if (Array.isArray(_val)) // 来源是数组，拆开push
            _target.push(..._val)
          else 
            _target.push(_val) // 不是数组直接push

        } else if (typeof _target === 'object') { // 对象，浅拷
          // Object.assign(_this[key], _val)
          copy(_this[key], _val)
          // 这里调用 copy 的话，可以递归深拷吧，不过不想做深拷。
        } else {
          if (isRef(_this[key])) { // 还得考虑 ref
            _this[key].value = _val
          } else {
            _this[key] = _val // 其他，赋值
          }
        }
      }
    } else {
      // 0，''，false，null，undefined，的情况
      if (typeof _val === 'undefined') {
        // 不处理
      } else {
        _this[key] = _val
      }
      // if (_val === '') {
      //  _this[key] = ''
      //} else if (_val === false) {
      //  _this[key] = false
      // }
    }
  })
}